#include <type_traits>
#include <iostream>

// 定义一个简单的结构体S来演示类型操作
struct S {
    int n;
    S(int m) : n(m) {}
    S& operator=(const S& other) {
        if (this != &other) {
            n = other.n;
        }
        return *this;
    }
};

template<typename T>
void processValue(const T& value) {
    // 使用std::remove_cv来确保处理的类型没有const或volatile限定符
    using CleanType = typename std::remove_cv<T>::type;
    CleanType modifiable = value; // 现在可以修改这个值

    std::cout << "Original value: " << value << ", modified value: " << ++modifiable << std::endl;
}

template<typename T>
void demonstratePointerBehavior(T* ptr) {
    // 演示指针类型的const限定符操作
    using PtrToConst = typename std::add_pointer<typename std::add_const<T>::type>::type;
    PtrToConst constPtr = ptr;

    std::cout << "Pointer points to: " << *constPtr << std::endl;
    // *constPtr = 100; // 错误：不能修改const指向的值
}

int main() {
    const int a = 55;
    processValue(a); // 将处理int类型的值

    int b = 27;
    demonstratePointerBehavior(&b); // 演示指向int的指针如何处理

    // 使用类型特征判断来决定类型行为
    if (std::is_constructible<S, int>::value && std::is_assignable<S&, const S&>::value) {
        S s1(10), s2(20);
        s1 = s2;
        std::cout << "s1.n = " << s1.n << std::endl;

        // 演示使用模板和类型特征结合的交换逻辑
        std::swap(s1, s2);
        std::cout << "After swap s1.n = " << s1.n << std::endl;
    } else {
        std::cout << "S类型不支持用int构造或不可赋值" << std::endl;
    }

    return 0;
}